#pragma once
#include <iostream>
#include <functional>
#include <string>
#include <unistd.h>
#include <pthread.h>
#include <cstring>
#include <cerrno>
#include "Log.hpp"

// using func_t = std::function<void(const std::string& name, pthread_mutex_t* lock)>;
using func_t = std::function<void(const std::string& name)>;
using namespace log_ns;
// typedef void*(*func_t)(void*);

const pthread_t ctid = -1;

class Thread {
private:
    void excute() {
        // std::cout << _name << " begin to run" << std::endl;
        // LOG(INFO, "%s begin to run\n", _name.c_str());
        _isrunning = true;
        _func(_name);
        _isrunning = false;
    }

    static void* ThreadRoutine(void* args) {
        Thread* self = static_cast<Thread*>(args);
        self->excute();
        return nullptr;
    }
public:
    Thread(func_t func, const std::string& name) 
        : _func(func),
          _isrunning(false),
          _tid(ctid),
          _name(name)
    {}

    ~Thread() {}

    void Start() {
        // 创建之后就开始运行了
        int n = pthread_create(&_tid, nullptr, ThreadRoutine, (void*)this);
        if (n != 0) {
            std::cout << "thread create failed!!!" << std::endl;
            exit(1);
        }
    }

    void Stop() {
        // 将线程暂停，使用
        if (_isrunning == false) return;
        // std::cout << _name << " stop " << std::endl;

        int n = ::pthread_cancel(_tid);
        if (n != 0)  {
            std::cout << "thread stop failed" << std::endl;
        }
        _isrunning = false;
    }

    void Join() {
        // 线程等待，
        if (_isrunning) return;
        int n = pthread_join(_tid, nullptr);
        if (n != 0) {
            std::cout << "thread wait failed!!!" << strerror(errno) << std::endl;
        }
        // std::cout << _name << " join " << std::endl;

    }

    std::string Status() {
        if (_isrunning) return "running";
        else return "sleep";
    }
private:
    pthread_t _tid;
    func_t _func;
    bool _isrunning;
    std::string _name;
};